package cn.itrip.auth.service;

import cn.itrip.beans.pojo.ItripUser;
import cn.itrip.common.MD5;
import cn.itrip.common.RedisAPI;
import cn.itrip.common.UserAgentUtil;
import com.alibaba.fastjson.JSON;
import cz.mallat.uasparser.UserAgentInfo;
import nl.bitwalker.useragentutils.UserAgent;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

@Service
public class TokenServiceImpl implements TokenService {

    @Resource
    private RedisAPI redisAPI;

    private String tokenPrefix = "token:";//统一加入 token前缀标识
    /***
     * @param agent Http头中的user-agent信息
     * @param user 用户信息
     * @return Token格式<br/>
     * 	PC：“前缀PC-USERCODE-USERID-CREATIONDATE-RONDEM[6位]”
     *  <br/>
     *  Android：“前缀ANDROID-USERCODE-USERID-CREATIONDATE-RONDEM[6位]”
     */
    @Override
    public String generateToken(String agent, ItripUser user) throws Exception {
        StringBuilder sb = new StringBuilder();
        sb.append(tokenPrefix);
//        UserAgentInfo userAgentInfo = UserAgentUtil.getUasParser().parse(agent);
//
//        switch (userAgentInfo.getDeviceType()) {
//            case UserAgentInfo.UNKNOWN:
//                if (UserAgentUtil.CheckAgent(agent)){
//                    sb.append("MOBILE-");
//                } else {
//                    sb.append("PC-");
//                }
//                break;
//            case "Personal computer":
//                sb.append("PC-");
//                break;
//            default:
//                sb.append("MOBILE-");
//                break;
//        }

        UserAgent userAgent = UserAgent.parseUserAgentString(agent);
        if (userAgent.getOperatingSystem().isMobileDevice()){
            sb.append("MOBILE-");
        } else {
            sb.append("PC-");
        }
        sb.append(MD5.getMd5(user.getUserCode(),32)+"-");
        sb.append(user.getId() + "-");
        sb.append(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
                + "-");
        sb.append(MD5.getMd5(agent, 6));// 识别客户端的简化实现——6位MD5码

        return sb.toString();
    }

    @Override
    public void save(String token, ItripUser user) throws Exception {
        if (token.startsWith(tokenPrefix+"PC-")){
            redisAPI.set(token,SESSION_TIMEOUT,JSON.toJSONString(user));
        } else {
            redisAPI.set(token, JSON.toJSONString(user));// 手机认证信息永不失效
        }
    }

    @Override
    public boolean validate(String agent, String token)  throws Exception{
        if (!redisAPI.exist(token)){
            return false;
        } else {
            String agentMd5 = token.split("-")[4];
            if (!MD5.getMd5(agent,6).equals(agentMd5)){
                return false;
            }
        }
        return true;
    }

    @Override
    public void delete(String token)  throws Exception {
        redisAPI.delete(token);
    }

    @Override
    public String reloadToken(String agent, String token) throws Exception {

        //1.验证token是否有效
        if (!redisAPI.exist(token))
            throw new Exception("token无效");

        //2.能不能置换，是否到了置换的时间
        Date genTime=new SimpleDateFormat("yyyyMMddHHmmss").parse(token.split("-")[3]);
        long passed = Calendar.getInstance().getTimeInMillis() - genTime.getTime();
        if (passed < REPLACEMENT_PROTECTION_TIMEOUT*1000)
            throw  new Exception("token置换保护期内，不能置换，剩余"+ (REPLACEMENT_PROTECTION_TIMEOUT*1000 - passed)/1000);

        //3.进行置换
        String userJson = redisAPI.get(token);
        ItripUser itripUser = JSON.parseObject(userJson,ItripUser.class);
        String newToken = this.generateToken(agent,itripUser);

        //4.老的token延期
        redisAPI.set(token,REPLACEMENT_DELAY,userJson);

        //5.新的token保存至redis
        this.save(newToken,itripUser);

        return newToken;
    }
}
